package com.bl.weilan.service.biz.companyfinancing.impl;

import com.bl.weilan.common.ApiResponseCode;
import com.bl.weilan.common.CommonServiceException;
import com.bl.weilan.common.utils.UUIDUtils;
import com.bl.weilan.dao.model.*;
import com.bl.weilan.dao.model.InstitutionCompanyEntity;
import com.bl.weilan.dao.repository.*;
import com.bl.weilan.service.biz.companyfinancing.CompanyFinancingService;
import com.bl.weilan.service.biz.companytrade.CompanyTradeService;
import com.bl.weilan.service.biz.tradedetail.TradeDetailService;
import com.bl.weilan.service.vo.DelBody;
import com.bl.weilan.service.vo.DelListBody;
import com.bl.weilan.service.vo.companyfinancing.CompanyFinancingAddVo;
import com.bl.weilan.service.vo.companyfinancing.CompanyFinancingListVo;
import com.bl.weilan.service.vo.companyfinancing.CompanyFinancingModVo;
import com.bl.weilan.service.vo.companytrade.CompanyTradeListVo;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

@Service
@Log4j2
public class CompanyFinancingServiceImpl implements CompanyFinancingService {
    @Autowired
    CompanyFinancingRepository companyfinancingRepository;

    @Autowired
    CompanyInvesterRepository companyInvesterRepository;

    @Autowired
    CompanyRepository companyRepository;

    @Autowired
    InstitutionRepository institutionRepository;

    @Autowired
    InstitutionCompanyRepository institutionCompanyRepository;

    @Autowired
    CompanyTradeService companyTradeService;

    @Autowired
    TradeInstitutionRepository tradeInstitutionRepository;

    @Autowired
    TradeDetailService tradeDetailService;

    @Override
    public CompanyFinancingEntity getCompanyFinancingById(String companyfinancingId) {
        CompanyFinancingEntity companyfinancingEntity = companyfinancingRepository.findOne(companyfinancingId);
        return companyfinancingEntity;
    }

    @Override
    public CompanyFinancingListVo getCompanyFinancingLists(String companyId, Pageable pageable ){
        Page<CompanyFinancingEntity> companyfinancingEntities;
        CompanyFinancingListVo companyfinancingListVo = new CompanyFinancingListVo();

        companyfinancingEntities = companyfinancingRepository.findByCompanyIdOrderByTime(companyId,pageable);


        companyfinancingListVo.setTotalCount(companyfinancingEntities.getTotalElements());
        companyfinancingListVo.setList(companyfinancingEntities.getContent());

        return companyfinancingListVo;
    }

    @Override
    public void addCompanyFinancing(CompanyFinancingAddVo companyfinancingAddVo) {
        CompanyFinancingEntity companyfinancingEntity = new CompanyFinancingEntity();
        companyfinancingEntity.setId(UUIDUtils.getUUID());
        BeanUtils.copyProperties(companyfinancingAddVo, companyfinancingEntity);
        companyfinancingEntity.setUpdateTime(new Date());
        companyfinancingRepository.save(companyfinancingEntity);



        CompanyTradeListVo companyTradeListVo = companyTradeService.getListByCompanyId(companyfinancingAddVo.getCompanyId());
        List<CompanyTradeEntity> companyTradeEntityList = companyTradeListVo.getList();


        List<String> investerList = Arrays.asList(companyfinancingAddVo.getInvestor().split(";"));//根据逗号分隔转化为list

        for (String invester : investerList) {

            CompanyEntity companyEntityInvester = companyRepository.findByFullName(invester);
            CompanyEntity companyEntity = companyRepository.findOne(companyfinancingAddVo.getCompanyId());
            if (companyEntityInvester != null) {
                // 公司对外投资增加
                CompanyInvesterEntity companyInvesterEntity = new CompanyInvesterEntity();
                companyInvesterEntity.setId(UUIDUtils.getUUID());
                companyInvesterEntity.setCompanyId(companyEntityInvester.getId());
                companyInvesterEntity.setFinancingId(companyfinancingEntity.getId());
                companyInvesterEntity.setInvestedId(companyEntity.getId());
                companyInvesterEntity.setPay(companyfinancingEntity.getMoney());
                companyInvesterEntity.setPercent(companyfinancingEntity.getPercent());
                companyInvesterEntity.setInvestedName(companyEntity.getFullName());
                companyInvesterEntity.setUpdateTime(new Date());
                companyInvesterRepository.save(companyInvesterEntity);
            }

            InstitutionEntity institutionEntity = institutionRepository.findByFullName(invester);
            if (institutionEntity != null) {
                // 机构增加投资
                InstitutionCompanyEntity institutionCompanyEntity = new InstitutionCompanyEntity();
                institutionCompanyEntity.setCompanyId(companyfinancingAddVo.getCompanyId());
                institutionCompanyEntity.setId(UUIDUtils.getUUID());
                institutionCompanyEntity.setFinancingId(companyfinancingEntity.getId());
                institutionCompanyEntity.setInstitutionId(institutionEntity.getId());
                institutionCompanyEntity.setMoney(companyfinancingAddVo.getMoney());
                institutionCompanyEntity.setTime(companyfinancingAddVo.getTime());
                institutionCompanyEntity.setMoneyString(companyfinancingAddVo.getMoneyString());
                institutionCompanyEntity.setUpdateTime(new Date());
                institutionCompanyRepository.save(institutionCompanyEntity);

                // 机构行业增加关联
                for (CompanyTradeEntity companyTradeEntity :companyTradeEntityList) {
                    // 二级行业关联
                    TradeInstitutionEntity tradeInstitutionEntity = tradeInstitutionRepository.findByTradeIdAndInstitutionId(companyTradeEntity.getTradeB(), institutionEntity.getId());
                    if (tradeInstitutionEntity == null) {
                        tradeInstitutionEntity = new TradeInstitutionEntity();
                        tradeInstitutionEntity.setId(UUIDUtils.getUUID());
                        tradeInstitutionEntity.setInstitutionId(institutionEntity.getId());
                        tradeInstitutionEntity.setTradeId(companyTradeEntity.getTradeB());
                        tradeInstitutionEntity.setNum(1);
                        tradeInstitutionEntity.setUpdateTime(new Date());
                    } else {
                        tradeInstitutionEntity.setNum(tradeInstitutionEntity.getNum() + 1);
                        tradeInstitutionEntity.setUpdateTime(new Date());
                    }
                    tradeInstitutionRepository.save(tradeInstitutionEntity);
                    // 三级行业关联
                    TradeInstitutionEntity tradeInstitutionEntity1 = tradeInstitutionRepository.findByTradeIdAndInstitutionId(companyTradeEntity.getTradeC(), institutionEntity.getId());
                    if (tradeInstitutionEntity1 == null) {
                        tradeInstitutionEntity1 = new TradeInstitutionEntity();
                        tradeInstitutionEntity1.setId(UUIDUtils.getUUID());
                        tradeInstitutionEntity1.setInstitutionId(institutionEntity.getId());
                        tradeInstitutionEntity1.setTradeId(companyTradeEntity.getTradeC());
                        tradeInstitutionEntity1.setNum(1);
                        tradeInstitutionEntity1.setUpdateTime(new Date());
                    } else {
                        tradeInstitutionEntity1.setNum(tradeInstitutionEntity.getNum() + 1);
                        tradeInstitutionEntity1.setUpdateTime(new Date());

                    }
                    tradeInstitutionRepository.save(tradeInstitutionEntity1);
                }
            }
        }

        Date date = companyfinancingAddVo.getTime();
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        int year = c.get(Calendar.YEAR);


        for (CompanyTradeEntity companyTradeEntity :companyTradeEntityList) {
            // 行业投资金额
            tradeDetailService.addFinacing(companyTradeEntity.getTradeB(), year, companyfinancingAddVo.getMoney());
            tradeDetailService.addFinacing(companyTradeEntity.getTradeC(), year, companyfinancingAddVo.getMoney());
            // 行业投资轮次
            tradeDetailService.addFinacingRound(companyTradeEntity.getTradeB(), companyfinancingAddVo.getRounds(), year);
            tradeDetailService.addFinacingRound(companyTradeEntity.getTradeC(), companyfinancingAddVo.getRounds(), year);
            // 行业投资事件
            tradeDetailService.addFinacingThing(companyTradeEntity.getTradeB(), year);
            tradeDetailService.addFinacingThing(companyTradeEntity.getTradeC(), year);
            // 行业总估值
            tradeDetailService.addValuations(companyTradeEntity.getTradeB(), year, companyfinancingAddVo.getValuation());
            tradeDetailService.addValuations(companyTradeEntity.getTradeC(), year, companyfinancingAddVo.getValuation());
        }

    }

    @Transactional
    @Override
    public void del(DelBody id) {
        CompanyFinancingEntity financingEntity = companyfinancingRepository.findOne(id.getId());
        companyfinancingRepository.delete(id.getId());
        companyInvesterRepository.deleteByFinancingId(id.getId());
        institutionCompanyRepository.deleteByFinancingId(id.getId());

        CompanyTradeListVo companyTradeListVo = companyTradeService.getListByCompanyId(financingEntity.getCompanyId());
        List<CompanyTradeEntity> companyTradeEntityList = companyTradeListVo.getList();

        List<String> investerList = Arrays.asList(financingEntity.getInvestor().split(";"));//根据逗号分隔转化为list

        for (String invester : investerList) {
            InstitutionEntity institutionEntity = institutionRepository.findByFullName(invester);
            if (institutionEntity != null) {
                // 减少机构行业关联
                for (CompanyTradeEntity companyTradeEntity :companyTradeEntityList) {
                    // 二级行业关联
                    TradeInstitutionEntity tradeInstitutionEntity = tradeInstitutionRepository.findByTradeIdAndInstitutionId(companyTradeEntity.getTradeB(), institutionEntity.getId());
                    if (tradeInstitutionEntity == null) {
                        throw new NullPointerException("tradeInstitutionEntity is null");
                    } else {
                        if (tradeInstitutionEntity.getNum() >= 1) {
                            tradeInstitutionEntity.setNum(tradeInstitutionEntity.getNum() - 1);
                            tradeInstitutionRepository.save(tradeInstitutionEntity);
                        } else {
                            tradeInstitutionRepository.delete(tradeInstitutionEntity.getId());
                        }
                    }
                    // 三级行业关联
                    TradeInstitutionEntity tradeInstitutionEntity1 = tradeInstitutionRepository.findByTradeIdAndInstitutionId(companyTradeEntity.getTradeC(), institutionEntity.getId());
                    if (tradeInstitutionEntity1 == null) {
                        throw new NullPointerException("tradeInstitutionEntity is null");
                    } else {
                        if (tradeInstitutionEntity1.getNum() >= 1) {
                            tradeInstitutionEntity1.setNum(tradeInstitutionEntity1.getNum() - 1);
                            tradeInstitutionRepository.save(tradeInstitutionEntity1);
                        } else {
                            tradeInstitutionRepository.delete(tradeInstitutionEntity1.getId());
                        }
                    }
                }
            }
        }

        // 行业图表减少
        Date date = financingEntity.getTime();
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        int year = c.get(Calendar.YEAR);
        for (CompanyTradeEntity companyTradeEntity :companyTradeEntityList) {
            // 行业投资金额
            tradeDetailService.delFinacing(companyTradeEntity.getTradeB(), year, (int)financingEntity.getMoney());
            tradeDetailService.delFinacing(companyTradeEntity.getTradeC(), year, (int)financingEntity.getMoney());
            // 行业投资轮次
            tradeDetailService.delFinacingRound(companyTradeEntity.getTradeB(), financingEntity.getRounds(), year);
            tradeDetailService.delFinacingRound(companyTradeEntity.getTradeC(), financingEntity.getRounds(), year);
            // 行业投资事件
            tradeDetailService.delFinacingThing(companyTradeEntity.getTradeB(), year);
            tradeDetailService.delFinacingThing(companyTradeEntity.getTradeC(), year);
            // 行业总估值
            tradeDetailService.delValuations(companyTradeEntity.getTradeB(), year, (int)financingEntity.getValuation());
            tradeDetailService.delValuations(companyTradeEntity.getTradeC(), year, (int)financingEntity.getValuation());
        }
    }

    @Transactional
    @Override
    public void delList(DelListBody idList) {
        for(String id : idList.getList()) {
            companyfinancingRepository.delete(id);
            companyInvesterRepository.deleteByFinancingId(id);
            institutionCompanyRepository.deleteByFinancingId(id);
        }
    }

    @Override
    public void modify(CompanyFinancingModVo companyfinancingModVo){
        CompanyFinancingEntity companyfinancingEntity = companyfinancingRepository.findOne(companyfinancingModVo.getId());

        if (companyfinancingEntity == null) {
            throw new CommonServiceException(ApiResponseCode.DATA_INCORRECT.getCode(), "没有对应信息");
        }
        BeanUtils.copyProperties(companyfinancingModVo, companyfinancingEntity);
        companyfinancingRepository.save(companyfinancingEntity);
    }

    @Override
    public float getCompanyFinanceThisYear(String companyId) {
        Calendar calendar1 = Calendar.getInstance();
        Date nowDate = new Date();
        calendar1.setTime(nowDate);
        String nowYear = String.valueOf(calendar1.get(Calendar.YEAR));

        float total = 0;
        List<CompanyFinancingEntity> companyFinancingEntities;

        companyFinancingEntities = companyfinancingRepository.findByCompanyId(companyId);

        for (CompanyFinancingEntity companyFinancingEntity : companyFinancingEntities) {
            Date finaingDate = companyFinancingEntity.getTime();
            if (calendar1 == null) {
                continue;
            }
            calendar1.setTime(finaingDate);
            String finaingYear = String.valueOf(calendar1.get(Calendar.YEAR));
            if (nowYear.equals(finaingYear)) {
                total += companyFinancingEntity.getMoney();
            }
        }
        return total;
    }
}
